package com.xgq.drink.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xgq.drink.controller.AliPayController;
import com.xgq.drink.entity.*;
import com.xgq.drink.entity.dto.CompositeOrderQuery;
import com.xgq.drink.mapper.*;
import com.xgq.drink.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xgq.drink.utils.BigDecimalUtils;
import com.xgq.drink.utils.OrderAmountCalculator;
import com.xgq.drink.utils.UniqueIdGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.management.Attribute;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 订单表 服务实现类
 * </p>
 *
 * @author xgq
 * @since 2025-03-03
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Orders> implements IOrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private IOrderProductService orderProductService;
    @Autowired
    private OrderSnapshotMapper orderSnapshotMapper;
    @Autowired
    private IOrderCancelOrRefundService orderCancelOrRefundService;
    @Autowired
    private IDiscountClaimService discountClaimService;
    @Autowired
    private IProductService productService;
    @Autowired
    private IUserService userService;
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private IPaymentService paymentService;
    @Autowired
    private IOrderLogisticsService orderLogisticsService;
    @Autowired
    private OrderAmountCalculator orderAmountCalculator;
    @Autowired
    private DiscountInfoMapper discountInfoMapper;
    @Autowired
    private AttributeProductMapper attributeProductMapper;
    @Autowired
    private IAddressService addressService;
    @Autowired
    private IAttributeProductService attributeProductService;

    public void placeOrder(Long productId, int quantity) {
        final int MAX_RETRIES = 3; // 最大重试次数
        int retries = 0;
        while (retries < MAX_RETRIES) {
            Product product = productService.getById(productId);
            if (product == null) {
                throw new RuntimeException("商品不存在");
            }
            if (product.getQuantity() < quantity) {
                throw new RuntimeException("商品库存不足");
            }
            product.setQuantity(product.getQuantity() - quantity);
            boolean updatedRows = productService.updateById(product);
            if (updatedRows) {
                return; // 更新成功，退出方法
            }
            retries++;
        }
        throw new RuntimeException("下单失败，商品信息已被其他用户修改，请稍后再试！");
    }
    public List<Orders> saveOrder(List<Product> products, Long userId, Long addressId) {
        Map<Long, List<Product>> brandGroups = products.stream()
                .collect(Collectors.groupingBy(Product::getBrandId));
        List<Orders> allOrders = new ArrayList<>();
        for (Map.Entry<Long, List<Product>> entry : brandGroups.entrySet()) {
            Long brandId = entry.getKey();
            List<Product> brandProducts = entry.getValue();
            // 减少当前品牌商品的库存
            for (Product product : brandProducts) {
                placeOrder(product.getProductId(), product.getBuyNum());
            }
            // 创建品牌订单
            Orders order = new Orders();
            order.setOrderId(UniqueIdGenerator.generateUniqueId());
            order.setStoreId(brandId);  // 新增店铺ID字段
            order.setUserId(userId);
            order.setProductNum(brandProducts.size());
            // 创建订单商品关联
            List<OrderProduct> orderProducts = new ArrayList<>();
            for (Product product : brandProducts) {
                OrderProduct orderProduct = new OrderProduct();
                orderProduct.setOrderId(order.getOrderId());
                orderProduct.setOrderProductId(UniqueIdGenerator.generateUniqueId());
                orderProduct.setProductId(product.getProductId());
                orderProduct.setProductName(product.getName());
                orderProduct.setProductPrice(product.getPrice());
                orderProduct.setProductQuantity(product.getBuyNum());
                orderProduct.setDiscountId(product.getDiscountId());
                orderProduct.setAttributeId(product.getAttributeId());
                orderProduct.setCurrentPrice(orderAmountCalculator.calculateDiscountAmount(
                        product.getPrice(),discountInfoMapper.selectById(product.getDiscountId())));
                orderProducts.add(orderProduct);
            }
            // 计算订单金额
            order.setTotalAmount(OrderAmountCalculator.calculateOrderAmounts(orderProducts));
            order.setPayAmount(OrderAmountCalculator.calculateOrderAmountsToFinal(orderProducts));
            order.setStatus(1);
            order.setAddress(addressId);
            // 保存订单及关联数据
            orderMapper.insert(order);
            orderProductService.saveOrderProducts(orderProducts);
            // 创建快照
            for (OrderProduct product : orderProducts) {
                OrderSnapshot snapshot = new OrderSnapshot();
                snapshot.setOrderId(order.getOrderId());
                snapshot.setUserId(userId);
                snapshot.setProductId(product.getProductId());
                snapshot.setProductName(product.getProductName());
                snapshot.setProductPrice(product.getProductPrice());
                snapshot.setProductQuantity(product.getProductQuantity());
                snapshot.setDiscount(product.getDiscountId());
                snapshot.setCurrentPrice(product.getCurrentPrice());
                snapshot.setSnapshotTime(LocalDateTime.now());
                orderSnapshotMapper.insert(snapshot);
                if (product.getDiscountId() != null) {
                    discountClaimService.markAsUsed(product.getDiscountId());
                }
            }
            allOrders.add(order);
        }
        return allOrders;
    }
    //查询订单列表
    public IPage<Orders> getOrderList(int current, int size, String status) {
        Page<Orders> page = new Page<>(current, size);
        QueryWrapper<Orders> queryWrapper = new QueryWrapper<>();
        if (status != null) {
            queryWrapper.eq("status", status);
        }
        IPage<Orders> ordersPage = orderMapper.selectPage(page, queryWrapper);
        return orderMapper.selectPage(page, queryWrapper);
    }
    @Override
    public Orders updateOrderStatus(Orders order) {
        Orders existingOrder = orderMapper.selectById(order.getOrderId());
        if (existingOrder != null) {
            // 新增退款状态处理
            if (order.getStatus() == 7) { // 7: 已退款
                processRefund(existingOrder);
            }
            existingOrder.setStatus(order.getStatus());
            orderMapper.updateById(existingOrder);
        }
        return existingOrder;
    }
    private void processRefund(Orders order) {
        // 1. 调用支付服务退款
        Payment payment = paymentService.getPaymentByOrderId(order.getOrderId());
        if (payment != null && payment.getPaymentStatus() == 2) { // 2: 支付成功
            try {
                // 调用支付宝退款接口
                boolean refundResult = paymentService.refund(
                        String.valueOf(order.getOrderId()),
                        order.getPayAmount()
                );

                if (refundResult) {
                    // 2. 更新支付状态为已退款
                    payment.setPaymentStatus(3);
                    paymentService.updatePayment(payment);
                } else {
                    throw new RuntimeException("支付宝退款失败");
                }
            } catch (Exception e) {
                throw new RuntimeException("退款处理失败：" + e.getMessage());
            }
        }

        // 3. 更新订单取消记录状态
        QueryWrapper<OrderCancelOrRefund> wrapper = new QueryWrapper<>();
        wrapper.eq("order_id", order.getOrderId())
                .eq("type", 1); // 1: 退款/退货
        OrderCancelOrRefund refund = orderCancelOrRefundService.getOne(wrapper);
        if (refund != null) {
            refund.setStatus(1); // 1: 已处理
            orderCancelOrRefundService.updateById(refund);
        }
    }
    public void confirmReceipt(Long orderId, Long userId) {
        Orders existingOrder = orderMapper.selectById(orderId);
        if (existingOrder == null) {
            throw new RuntimeException("订单不存在");
        }

        if (!existingOrder.getUserId().equals(userId)) {
            throw new RuntimeException("用户无权限操作该订单");
        }

        if (!existingOrder.getStatus().equals(3)) {
            throw new RuntimeException("订单状态不允许确认收货");
        }

        // 更新订单状态为待评价
        existingOrder.setStatus(4); // 4: 待评价
        existingOrder.setUpdatedAt(LocalDateTime.now());
        // 获取订单金额并转换为积分
        BigDecimal orderAmount = existingOrder.getPayAmount();
        int pointsToAdd = BigDecimalUtils.convertAmountToPoints(orderAmount);

        // 查询用户当前积分
        User user = userService.getById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 更新用户积分
        user.setPoints(user.getPoints() + pointsToAdd);
        userService.updateById(user);
        orderMapper.updateById(existingOrder);
    }

    public Orders updateOrder(Orders order) {
        // 只允许修改地址和退款
        Orders existingOrder = orderMapper.selectById(order.getOrderId());
        if (existingOrder != null) {
            if (order.getAddress() != null) {
                existingOrder.setAddress(order.getAddress());
            }
            if (order.getDiscount() != null) {
                existingOrder.setDiscount(order.getDiscount());
            }
            orderMapper.updateById(existingOrder);
        }
        return existingOrder;
    }
    @Override
    public IPage<Orders> getUserOrderList(Long userId, int current, int size, Integer status) {
        // 创建分页对象
        Page<Orders> page = new Page<>(current, size);
        // 创建查询条件包装器
        QueryWrapper<Orders> queryWrapper = new QueryWrapper<>();
        // 添加用户ID查询条件
        queryWrapper.eq("user_id", userId);
        // 如果状态不为空，添加状态查询条件
        if (status != null) {
            queryWrapper.eq("status", status);
        }
        // 执行查询
        return orderMapper.selectPage(page, queryWrapper);
    }
    public Orders cancelOrder(Orders order, String reason) {
        Orders existingOrder = orderMapper.selectById(order.getOrderId());
        if (existingOrder != null && existingOrder.getStatus() == 1) {
            existingOrder.setStatus(6); // 设置状态为订单取消中
            orderMapper.updateById(existingOrder);
            // 记录取消订单
            OrderCancelOrRefund cancelRecord = new OrderCancelOrRefund();
            cancelRecord.setId(UniqueIdGenerator.generateUniqueId());
            cancelRecord.setOrderId(order.getOrderId());
            cancelRecord.setUserId(order.getUserId());
            cancelRecord.setType(0); // 0: 取消订单
            cancelRecord.setReason(reason);
            cancelRecord.setStatus(0); // 0: 待处理
            cancelRecord.setCreatedAt(LocalDateTime.now());
            orderCancelOrRefundService.save(cancelRecord);
        }
        return existingOrder;
    }
    /**
     * 用户申请退货
     * @param order 订单信息
     * @param reason 退货原因
     */
    public void refundOrder(Orders order, String reason) {
        Orders existingOrder = orderMapper.selectById(order.getOrderId());
        if (existingOrder != null && (existingOrder.getStatus() == 2 || existingOrder.getStatus() == 3)) {
            existingOrder.setStatus(5); // 设置状态为退款/售后中
            orderMapper.updateById(existingOrder);

            // 记录退款申请
            OrderCancelOrRefund refundRecord = new OrderCancelOrRefund();
            refundRecord.setId(UniqueIdGenerator.generateUniqueId());
            refundRecord.setOrderId(order.getOrderId());
            refundRecord.setUserId(order.getUserId());
            refundRecord.setType(1); // 1: 退款/退货
            refundRecord.setReason(reason);
            refundRecord.setStatus(0); // 0: 待处理
            refundRecord.setCreatedAt(LocalDateTime.now());
            orderCancelOrRefundService.save(refundRecord);
        }
    }
    // 根据订单ID获取订单详情
    public Orders getOrderById(String orderId) {
        return orderMapper.selectById(orderId);
    }
    // 商家查询订单
    @Override
    public IPage<Orders> getBrandOrderList(Long brandId, int current, int size, Integer status) {
        Page<Orders> page = new Page<>(current, size);
        QueryWrapper<Orders> queryWrapper = new QueryWrapper<>();

        // 直接通过店铺ID查询
        queryWrapper.eq("store_id", brandId);

        if (status!= null&&status!=0) {
            queryWrapper.eq("status", status);
        }
        queryWrapper.orderByDesc("created_at");

        return orderMapper.selectPage(page, queryWrapper);
    }
    //发货
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Orders shipOrder(Long orderId, String logisticsNumber) {
        Orders order = orderMapper.selectById(orderId);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        if (order.getStatus() != 2) {
            throw new RuntimeException("订单状态不是待发货，无法执行发货操作");
        }
        // 更新订单状态为待收货
        order.setStatus(3);
        order.setUpdatedAt(LocalDateTime.now());
        orderMapper.updateById(order);
        // 如果提供了物流单号，记录物流信息
        if (logisticsNumber != null && !logisticsNumber.isEmpty()) {
            OrderLogistics logistics = new OrderLogistics();
            logistics.setOrderId(orderId);
            logistics.setLogisticsNumber(logisticsNumber);
            logistics.setStatus("已发货");
            logistics.setCreatedAt(LocalDateTime.now());
            logistics.setUpdatedAt(LocalDateTime.now());
            orderLogisticsService.save(logistics);
        }
        return order;
    }
    //取消订单
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Orders closeBrandOrder(Long orderId, String reason) {
        Orders order = orderMapper.selectById(orderId);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        
        // 只有待付款的订单才能被商家关闭
        if (order.getStatus() != 1) {
            throw new RuntimeException("只有待付款的订单才能被关闭");
        }
        
        // 更新订单状态为已取消
        order.setStatus(6);
        order.setUpdatedAt(LocalDateTime.now());
        orderMapper.updateById(order);
        
        // 记录订单取消信息
        OrderCancelOrRefund cancelRecord = new OrderCancelOrRefund();
        cancelRecord.setId(UniqueIdGenerator.generateUniqueId());
        cancelRecord.setOrderId(orderId);
        cancelRecord.setUserId(null); // 由商家发起的关闭，不关联用户
        cancelRecord.setType(0); // 0: 取消订单
        cancelRecord.setReason(reason);
        cancelRecord.setStatus(1); // 1: 已处理
        cancelRecord.setCreatedAt(LocalDateTime.now());
        cancelRecord.setUpdatedAt(LocalDateTime.now());
        orderCancelOrRefundService.save(cancelRecord);
        
        return order;
    }

    @Override
    public Integer getOrderCountByBrandIdAndTimeRange(Long brandId, LocalDateTime startTime, LocalDateTime endTime) {
        QueryWrapper<Orders> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("store_id", brandId);
        if (startTime != null) {
            queryWrapper.ge("created_at", startTime);
        }
        if (endTime != null) {
            queryWrapper.le("created_at", endTime);
        }
        return Math.toIntExact(orderMapper.selectCount(queryWrapper));
    }

    @Override
    public BigDecimal getTotalAmountByBrandIdAndTimeRange(Long brandId, LocalDateTime startTime, LocalDateTime endTime) {
        QueryWrapper<Orders> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("store_id", brandId);
        if (startTime != null) {
            queryWrapper.ge("created_at", startTime);
        }
        if (endTime != null) {
            queryWrapper.le("created_at", endTime);
        }
        List<Orders> orders = orderMapper.selectList(queryWrapper);
        return orders.stream()
                .map(Orders::getTotalAmount)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }
    @Override
    public IPage<Orders> getCompositeOrders(CompositeOrderQuery query) {
        // 基础查询条件
        Page<Orders> page = new Page<>(query.getCurrent(), query.getSize());
        QueryWrapper<Orders> wrapper = new QueryWrapper<>();
        System.out.println("查询条件：");
        System.out.println(query);
        // 原有条件设置
        wrapper.eq(query.getBrandId() != null, "store_id", query.getBrandId())
                .eq(query.getStatus() != 0, "status", query.getStatus())
                .between(query.getStartTime() != null && query.getEndTime() != null,
                        "created_at", query.getStartTime(), query.getEndTime())
                .ge(query.getMinAmount() != null, "total_amount", query.getMinAmount())
                .le(query.getMaxAmount() != null, "total_amount", query.getMaxAmount())
                .eq(query.getUserId() != null, "user_id", query.getUserId())
                .eq(query.getOrderId() != null, "order_id", query.getOrderId());
        // 执行基础查询
        IPage<Orders> orderPage = orderMapper.selectPage(page, wrapper);
        System.out.println(orderPage);
        // 数据组合处理
        orderPage.getRecords().forEach(order -> {
            // 1. 查询订单商品明细
            List<OrderProduct> orderProducts = orderProductService.list(
                    new QueryWrapper<OrderProduct>().eq("order_id", order.getOrderId())
            );

            // 2. 获取完整商品信息
            orderProducts.forEach(op -> {
                // 获取商品详情
                Product product = productService.getById(op.getProductId());
                op.setProductDetail(product);
                AttributeProduct attribute = attributeProductService.getById(op.getAttributeId());
                op.setAttributeProduct(attribute);
            });

            // 3. 设置组合数据
            order.setOrderProducts(orderProducts);
            order.setAddressInfo(addressService.getById(order.getAddress()));
        });

        return orderPage;
    }

}
